﻿//
//
/////////////////////////////////////////////////////////////////////////////

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

/////////////////////////////////////////////////////////////////////////////
namespace ThinControlLibrary
{
    /////////////////////////////////////////////////////////////////////////
    /// <summary>
    /// Interaction logic for DigitNumberControl.xaml
    /// </summary>
    public partial class DigitNumberControl : UserControl
    {
        private byte _value;
        private Polygon[] _numberParts = new Polygon[8];
        private double _highOpacityLevel = 1;
        private double _lowOpacityLevel = 0.2;

        /////////////////////////////////////////////////////////////////////
        public DigitNumberControl()
        {
            InitializeComponent();

            this.Loaded += (sender, args) =>
                               {
                                   Canvas canvas = contentControl.Template.FindName("DigitalCanvas", contentControl) as Canvas;
                                   if (canvas != null)
                                   {
                                       _numberParts[1] = contentControl.Template.FindName("middlePolygon", contentControl) as Polygon;
                                       _numberParts[2] = contentControl.Template.FindName("centerTopPolygon", contentControl) as Polygon;
                                       _numberParts[3] = contentControl.Template.FindName("leftTopPolygon", contentControl) as Polygon;
                                       _numberParts[4] = contentControl.Template.FindName("leftBottomPolygon", contentControl) as Polygon;
                                       _numberParts[5] = contentControl.Template.FindName("centerBottomPolygon", contentControl) as Polygon;
                                       _numberParts[6] = contentControl.Template.FindName("rightBottomPolygon", contentControl) as Polygon;
                                       _numberParts[7] = contentControl.Template.FindName("rightTopPolygon", contentControl) as Polygon;
                                       
                                       foreach (Polygon polygon in _numberParts.Where(polygon => polygon != null))
                                       {
                                           polygon.Opacity = _lowOpacityLevel;
                                       }
                                   }
                               };
        }

        /////////////////////////////////////////////////////////////////////
        public byte Value
        {
            get { return _value; }
            set
            {
                if (value < 0 || value > 9)
                {
                    throw new ArgumentException("Value is out of range and should be between 0 and 9.", "value");
                }
                _value = value;
                _switchDigitalDisplay();
            }
        }

        public double HighOpacityLevel
        {
            get { return _highOpacityLevel; }
            set { _highOpacityLevel = value; }
        }

        public double LowOpacityLevel
        {
            get { return _lowOpacityLevel; }
            set { _lowOpacityLevel = value; }
        }

        /////////////////////////////////////////////////////////////////////
        private void _switchDigitalDisplay()
        {
            BitArray mask = NumbersMasks.GetMask(_value);
            for (int i = 1; i < 8; i++)
            {
                bool show = mask[i];
                if (show)
                {
                    _numberParts[i].Opacity = 1;
                }
                else if (_numberParts[i].Opacity == 1.0)
                {
                    _fadeDigitalPolygonPart(_numberParts[i]);
                }
            }
        }

        private void _fadeDigitalPolygonPart(Polygon polygon)
        {
            DoubleAnimation fade = new DoubleAnimation()
            {
                From = 1,
                To = 0.2,
                Duration = TimeSpan.FromSeconds(0.2),
            };
            fade.Completed += (sender, args) =>
                                  {
                                      polygon.BeginAnimation(Polygon.OpacityProperty, null);
                                      polygon.Opacity = 0.2;
                                  };

            Storyboard.SetTarget(fade, polygon);
            Storyboard.SetTargetProperty(fade, new PropertyPath(Polygon.OpacityProperty));

            var sb = new Storyboard();
            sb.Children.Add(fade);
            sb.Begin();
        }

        /////////////////////////////////////////////////////////////////////
        private static class NumbersMasks
        {
            /*      
             *    __F__
             * E |     | A
             *   |__G__|
             * D |     | B
             *   |_____|
             *      C
             * 
             * */

            /*     0 1 2 3 4 5 6 7
             *     - G F E D C B A 
             *  1 |0 0 0 0 0 0 1 1 | 252
             *  2 |0 1 1 0 1 1 0 1 | 192
             *  3 |0 1 1 0 0 1 1 1 | 182
             *  4 |0 1 0 1 0 0 1 1 | 230
             *  5 |0 1 1 1 0 1 1 0 | 202
             *  6 |0 1 1 1 1 1 1 0 | 110
             *  7 |0 0 1 0 0 0 1 1 | 126
             *  8 |0 1 1 1 1 1 1 1 | 196
             *  9 |0 1 1 1 0 1 1 1 | 254
             *  0 |0 1 1 1 1 1 1 1 | 238
             */

            public static readonly BitArray Zero  = new BitArray(new byte[] { 252 });
            public static readonly BitArray One   = new BitArray(new byte[] { 192 }); 
            public static readonly BitArray Two   = new BitArray(new byte[] { 182 }); 
            public static readonly BitArray Three = new BitArray(new byte[] { 230 }); 
            public static readonly BitArray Four  = new BitArray(new byte[] { 202 }); 
            public static readonly BitArray Five  = new BitArray(new byte[] { 110 }); 
            public static readonly BitArray Six   = new BitArray(new byte[] { 126 }); 
            public static readonly BitArray Seven = new BitArray(new byte[] { 196 });  
            public static readonly BitArray Eight = new BitArray(new byte[] { 254 }); 
            public static readonly BitArray Nine  = new BitArray(new byte[] { 238 }); 

            /////////////////////////////////////////////////////////////////
            public static BitArray GetMask(byte bumber)
            {
                switch (bumber)
                {                                                                             
                    case 0:
                        return Zero;
                    case 1:
                        return One;
                    case 2:
                        return Two;
                    case 3:
                        return Three;
                    case 4:
                        return Four;
                    case 5:
                        return Five;
                    case 6:
                        return Six;
                    case 7:
                        return Seven;
                    case 8:
                        return Eight;
                    case 9:
                        return Nine;
                    default:
                        return Eight;
                }
            }
        }
    }
/////////////////////////////////////////////////////////////////////////////
}//ThinControlLibrary
